import websockets
import json
import time
import os
import sys
import socket
import asyncio
#import mysing
#from requests import get as requests_get
#from time import strftime
#from time import localtime
#from datetime import datetime
#import ntplib


model_dict = {}
game_dict = {}
root_members = {"members":set(),"root":set()}
my_queue = {"log":None,"members":set()}

mypath = os.path.dirname(os.path.abspath(sys.argv[0]))


#class mstsset:
#    run = True


#if mysing.my_stat.stat_:
#    mstsset.run=True


def log(st):
    with open(os.path.join(mypath,"The_log.log"),"a") as mi:
        mi.write(st + "\n")


def return_msg(user='server',typ_='str',msg='',report=False):
    msg_dict = {
        'user':user,
        'type':typ_,
        'msg':msg,
        'report':report
    }
    return json.dumps(msg_dict)


async def check_user_permit(websocket):
    recv_str = await websocket.recv()
    cred_dict = json.loads(recv_str)
    if int(time.strftime("%Y%m%d")) < 20230203:
        if not cred_dict['lgon']:
            if cred_dict['model'] in my_queue['members']:
                await websocket.send(return_msg(msg='黑名单',typ_='logon'))
                # print("黑名单拦截",cred_dict['model'])
                return False
            elif cred_dict['user'] == 'members':
                the_log = "{} || 成员接入: {}".format(time.strftime("%Y-%m-%d %H:%M:%S"),cred_dict['model'])
                # print(the_log)
                my_queue['log'].put({"type":"log","msg":the_log})
                log(the_log)
                root_members["members"].add(cred_dict['model'])
                game_dict.update({cred_dict['model']:cred_dict['game']})
                for i in root_members["root"]:
                    if i in model_dict:
                        await model_dict[i].send(return_msg(msg=(cred_dict['model'],cred_dict['game']),typ_='add'))
                    else:
                        root_members['root'].remove(i)
            elif cred_dict['user'] == 'root':
                the_log = "{} || 管理员接入: {} ".format(time.strftime("%Y-%m-%d %H:%M:%S"),cred_dict['model'])
                my_queue['log'].put({"type":"log","msg":the_log})
                root_members["root"].add(cred_dict['model'])
                # print(the_log)
                log(the_log)
            await websocket.send(return_msg(msg='登录成功',typ_='logon'))
            return cred_dict['model']
        else:
            await websocket.send(return_msg(msg='登录失败',typ_='logon'))
    return False


async def recv_user_msg(websocket):
    while True:
        ret_cmd = await websocket.recv()
        recv_dict = json.loads(ret_cmd)
        if recv_dict['user'] == 'root':
            if recv_dict['type'] == 'get-list':
                await websocket.send(return_msg(msg=game_dict,typ_=recv_dict['type']))
            elif not recv_dict['list']:
                for use in root_members["members"]:
                    if use in model_dict:
                        await model_dict[use].send(return_msg(user=recv_dict['model'],msg=recv_dict['msg'],typ_=recv_dict['type'],report=recv_dict['report']))
                    else:
                        root_members["members"].remove(use)
            else:
                for use in recv_dict['list']:
                    if use in model_dict:
                        await model_dict[use].send(return_msg(user=recv_dict['model'],msg=recv_dict['msg'],typ_=recv_dict['type'],report=recv_dict['report']))
                    elif use in root_members["members"]:
                        root_members["members"].remove(use)
                        await websocket.send(return_msg(user=use,msg='成员不在线',typ_=recv_dict['err']))
                    else:
                        await websocket.send(return_msg(user=use,msg='成员不在线',typ_=recv_dict['err']))
        elif recv_dict['user'] == 'members':
            if recv_dict['report']:
                if recv_dict['vivo'] in model_dict:
                    await model_dict[recv_dict['vivo']].send(return_msg(user=recv_dict['model'],msg=recv_dict['msg'],typ_=recv_dict['type'],report=recv_dict['report']))
                elif recv_dict['vivo'] in root_members["root"]:
                    root_members["root"].remove(recv_dict['vivo'])
                    await websocket.send(return_msg(user=recv_dict['vivo'],msg='管理员已下线',typ_=recv_dict['err']))
                else:
                    await websocket.send(return_msg(user=recv_dict['vivo'],msg='管理员已下线',typ_=recv_dict['err']))
            elif recv_dict['type']=='upgame':
                game_dict.update({recv_dict['model']:recv_dict['game']})
                for i in root_members["root"]:
                    if i in model_dict:
                        await model_dict[i].send(return_msg(msg=(recv_dict['model'],recv_dict['game']),typ_='set'))
                    else:
                        root_members['root'].remove(i)


async def run(websocket, path):
    websocket_key = None
    try:
        websocket_key = await check_user_permit(websocket)
        if websocket_key:
            model_dict.update({websocket_key:websocket})
            await recv_user_msg(websocket)
    except Exception as e:
        if websocket_key in root_members["root"]:
            root_members["root"].remove(websocket_key)
            the_log = "{} || 管理员下线: {}".format(time.strftime("%Y-%m-%d %H:%M:%S"),websocket_key)
            my_queue['log'].put({"type":"log","msg":the_log})
            # print(the_log)
            log(the_log)
        elif websocket_key in root_members["members"]:
            root_members["members"].remove(websocket_key)
            the_log = "{} || 成员下线: {}".format(time.strftime("%Y-%m-%d %H:%M:%S"),websocket_key)
            my_queue['log'].put({"type":"log","msg":the_log})
            for i in root_members["root"]:
                if i in model_dict:
                    await model_dict[i].send(return_msg(msg=websocket_key,typ_='del'))
                else: 
                    root_members['root'].remove(i)
            # print(the_log)
            log(the_log)
        if websocket_key in game_dict:
            game_dict.pop(websocket_key)
        if websocket_key in model_dict:
            model_dict.pop(websocket_key)
    finally:
        pass


async def async_main(host,port):
    async with websockets.serve(run, host, port, ping_interval=None):
        await asyncio.Future()
